package com.jrx.anytxn.param.service.investor.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jrx.anytxn.common.constant.CommonContants;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.dto.investor.PrInvestorInterestRateReq;
import com.jrx.anytxn.param.dto.investor.PrInvestorInterestRateRes;
import com.jrx.anytxn.param.entity.PrInterestTable;
import com.jrx.anytxn.param.entity.PrInvestorInterestRate;
import com.jrx.anytxn.param.mapper.ext.ExtPrInvestorInterestRateMapper;
import com.jrx.anytxn.param.service.investor.IPrInvestorInterestRateService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

/**
 * 出资方利率表 service实现
 * @author 黄秋平
 * @date 2020-05-17 22:30
 **/
@Service
@CacheConfig(cacheNames = "INVESTOR_INTEREST")
public class PrInvestorInterestRateServiceImpl implements IPrInvestorInterestRateService {

    private static final Logger logger = LoggerFactory.getLogger(PrInvestorInterestRateServiceImpl.class);

    @Resource
    private ExtPrInvestorInterestRateMapper extPrInvestorInterestRateMapper;

    @Resource
    private ISegmentService segmentService;

    @Override
    public TxnPage<PrInvestorInterestRateRes> findAllPageByTenId(Integer pageNum, Integer pageSize, String tenantId) {
        Page<PrInvestorInterestRate> page = PageHelper.startPage(pageNum, pageSize, Constant.ORDER_BY_SORT);
        List<PrInvestorInterestRate> interestTableList = extPrInvestorInterestRateMapper.selectByTenId(tenantId);
        List<PrInvestorInterestRateRes> res = new LinkedList<>();
        if (interestTableList != null && !interestTableList.isEmpty()) {
            res = BeanMapping.copyList(interestTableList, PrInvestorInterestRateRes.class);
        }
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    @Override
    public PrInvestorInterestRateRes addInterestTable(PrInvestorInterestRateReq prInvestorInterestRateReq) throws TxnException {
        PrInvestorInterestRate prInvestorInterestRate = extPrInvestorInterestRateMapper.selectByTenIdAndInterestId(prInvestorInterestRateReq.getTenantId(), prInvestorInterestRateReq.getInvestorInterestId());
        if (prInvestorInterestRate != null) {
            logger.error(TxnRespCode.DATA_EXISTS.getMsg());
            throw new TxnException(TxnRespCode.DATA_EXISTS.getMsg());
        }
        PrInvestorInterestRate interestTable = BeanMapping.copy(prInvestorInterestRateReq, PrInvestorInterestRate.class);
        try {
            interestTable.setId(segmentService.getId(Constant.PR_INVESTOR_INTEREST_RATE));
        } catch (SegmentException e) {
            logger.error("主键生成错误",e);
            throw new TxnException(ErrorMsgConstant.ERROR_ID);
        }
        interestTable.setRecordVersionNumber(Constant.VERSION_NUMBER);
        extPrInvestorInterestRateMapper.insertSelective(interestTable);
        return BeanMapping.copy(interestTable, PrInvestorInterestRateRes.class);
    }

    @Override
    @CacheEvict(key = "'invertorInterest_'+#prInvestorInterestRateReq.tenantId+'_'+#prInvestorInterestRateReq.investorInterestId")
    public PrInvestorInterestRateRes modifyInterestTable(PrInvestorInterestRateReq prInvestorInterestRateReq) throws TxnException {
        PrInvestorInterestRate prInvestorInterestRate = extPrInvestorInterestRateMapper.selectByTenIdAndInterestId(prInvestorInterestRateReq.getTenantId(), prInvestorInterestRateReq.getInvestorInterestId());
        if (prInvestorInterestRate == null) {
            logger.error(TxnRespCode.NO_DATA.getMsg());
            throw new TxnException(TxnRespCode.NO_DATA.getMsg());
        }
        PrInvestorInterestRate interestTable = BeanMapping.copy(prInvestorInterestRateReq, PrInvestorInterestRate.class);
        // 更新
        extPrInvestorInterestRateMapper.updateByTenIdAndInterestId(interestTable);
        return BeanMapping.copy(interestTable, PrInvestorInterestRateRes.class);
    }

    @Override
    @CacheEvict(key = "'invertorInterest_'+#tenantId+'_'+#investorInterestId")
    public Boolean removeByTenIdAndInterestId(String tenantId, String investorInterestId) throws TxnException {
        if (StringUtils.isBlank(tenantId) || StringUtils.isBlank(investorInterestId)) {
            logger.error(TxnRespCode.NOT_EMPTY.getMsg());
            throw new TxnException(TxnRespCode.NOT_EMPTY.getMsg());
        }
        int i = extPrInvestorInterestRateMapper.deleteByTenIdAndInterestId(tenantId, investorInterestId);
        return i > 0;
    }

    @Override
    public PrInvestorInterestRateRes findByTenIdAndInterestId(String tenantId, String investorInterestId) throws TxnException {
        if (StringUtils.isBlank(tenantId) || StringUtils.isBlank(investorInterestId)) {
            logger.error(TxnRespCode.NOT_EMPTY.getMsg());
            throw new TxnException(TxnRespCode.NOT_EMPTY.getMsg());
        }
        PrInvestorInterestRate interestTable = extPrInvestorInterestRateMapper.selectByTenIdAndInterestId(tenantId, investorInterestId);
        return BeanMapping.copy(interestTable, PrInvestorInterestRateRes.class);
    }

    @Override
    @Cacheable(key = "'invertorInterest_'+#tenantId+'_'+#investorInterestId")
    public PrInvestorInterestRateRes findByInterestId(String investorInterestId, String orgId, String tenantId) throws TxnBizException {
        PrInvestorInterestRate interestTable = extPrInvestorInterestRateMapper.selectByInterestId(investorInterestId, orgId, tenantId);
        if (interestTable == null) {
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg(ErrorMsgConstant.NO_INTEREST_DATA));
        }
        return BeanMapping.copy(interestTable, PrInvestorInterestRateRes.class);
    }

    @Cacheable(key = "'invertorInterest_'+#tenantId+'_'+#investorInterestId")
    @Override
    public PrInvestorInterestRate findInterestByInterestId(String investorInterestId, String orgId, String tenantId) throws TxnBizException {
        PrInvestorInterestRate interestTable = extPrInvestorInterestRateMapper.selectByInterestId(investorInterestId, orgId, tenantId);
        if (interestTable == null) {
            throw new TxnBizException(TxnRespCode.NO_DATA.getCode(), TxnRespCode.NO_DATA.getMsg(ErrorMsgConstant.NO_INTEREST_DATA));
        }
        return interestTable;
    }

    /**
     * 日利率计算
     *
     * @param interest     利率信息
     * @param businessDate 当前业务日期
     * @return BigDecimal 日利率
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public BigDecimal getDailyRate(PrInvestorInterestRate interest, Date businessDate) {

        BigDecimal baseRate = interest.getBaseRate();// 初始利率 若是月则不需要复杂计算

        //利率变动类型 不是固定利率   基础利率*调整利率百分比
        if (!Constant.INT_CHANGE_TYPE_FIXED.equals(interest.getInterestChangeType()) && interest.getBaseRatePercent() != null) {
            baseRate = baseRate.multiply(interest.getBaseRatePercent());
        }

        //年利率基础参数
        int yearBase = getYearBase(interest.getYearBase());

        // 月利率基础参数
        int monthBase = getMonthBase(interest.getMonthBase(), businessDate);

        // 0-年利率
        if (Constant.INT_TYPE_YEAR.equalsIgnoreCase(interest.getRateType())) {//初始是年利率
            baseRate = baseRate.divide(
                    BigDecimal.valueOf(yearBase), CommonContants.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);
        } else if (Constant.INT_TYPE_MONTH.equalsIgnoreCase(interest.getRateType())) {// 初始是月利率
            baseRate = baseRate.divide(
                    BigDecimal.valueOf(monthBase), CommonContants.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);
        }
        return baseRate;
    }

    /**
     * 月利率计算
     *
     * @param interest     利率信息
     * @param businessDate 当前业务日期
     * @return BigDecimal 月利率
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public BigDecimal getMonthRate(PrInvestorInterestRate interest, Date businessDate) {

        BigDecimal baseRate = interest.getBaseRate();// 初始利率 若是月则不需要复杂计算
        //利率变动类型 不是固定利率   基础利率*调整利率百分比
        if (!Constant.INT_CHANGE_TYPE_FIXED.equals(interest.getInterestChangeType()) && interest.getBaseRatePercent() != null) {
            baseRate = baseRate.multiply(interest.getBaseRatePercent());
        }
        //月利率基础参数
        int monthBase = getMonthBase(interest.getMonthBase(), businessDate);
        // 初始是年利率
        if (Constant.INT_TYPE_YEAR.equalsIgnoreCase(interest.getRateType())) {
            baseRate = baseRate.divide(
                    new BigDecimal(CommonContants.MONTH), CommonContants.BIGDECIMAL_SCALE_7, BigDecimal.ROUND_HALF_UP);
        } else if (Constant.INT_TYPE_DAILY.equalsIgnoreCase(interest.getRateType())) {//初始是天利率
            baseRate = baseRate.multiply(new BigDecimal(monthBase));
        }
        return baseRate;
    }

    /**
     * 年利率计算
     *
     * @param interest 利率信息
     * @return BigDecimal 年利率
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public BigDecimal getYearRate(PrInvestorInterestRate interest) {

        BigDecimal baseRate = interest.getBaseRate();// 初始利率 若是年则不需要复杂计算

        if (!Constant.INT_CHANGE_TYPE_FIXED.equals(interest.getInterestChangeType()) && interest.getBaseRatePercent() != null) {//利率变动类型 不是固定利率
            baseRate = baseRate.multiply(interest.getBaseRatePercent());//基础利率乘以调整利率百分比
        }
        //年利率基础参数
        int yearBase = getYearBase(interest.getYearBase());

        if (Constant.INT_TYPE_MONTH.equalsIgnoreCase(interest.getRateType())) {// 若初始是月利率
            baseRate = baseRate.multiply(new BigDecimal(CommonContants.MONTH));
        } else if (Constant.INT_TYPE_DAILY.equalsIgnoreCase(interest.getRateType())) {//初始是日利率
            baseRate = baseRate.multiply(new BigDecimal(yearBase));
        }
        return baseRate;
    }

    /**
     * 获取年利率基础天数
     *
     * @param yearBaseParam 年利率基础因子
     * @return int 年利率基础天数
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public int getYearBase(String yearBaseParam) {
        switch (yearBaseParam) {
            case Constant.YEAR_360:
                return 360;
            case Constant.YEAR_366:
                GregorianCalendar gc = new GregorianCalendar();
                if (gc.isLeapYear(gc.get(GregorianCalendar.YEAR))) {
                    return 366;
                } else {
                    return 365;
                }
            default:
                return 365;
        }
    }

    /**
     * 获取年利率基础天数
     *
     * @param monthBaseParam 年利率基础因子
     * @return int年利率基础天数
     * @author liuyang
     * @date 2020-05-18
     */
    @Override
    public int getMonthBase(String monthBaseParam, Date businessDate) {
        switch (monthBaseParam) {
            case Constant.MONTH_BASE_D:
                return DateUtils.getTotalDaysOfMonth(businessDate);
            default:
                return 30;
        }
    }
}
